import 'dart:async';
import 'dart:io';

import 'package:easy_debounce/easy_debounce.dart';
import 'package:gate_cli/utils/intl_view/utils/intl_arb_file.dart';
import 'package:gate_cli/utils/intl_view/utils/intl_socket_server.dart';
import 'package:gate_cli/utils/intl_view/utils/run_intl_utils_package.dart';
import 'package:path/path.dart';

class ProjectIntl {
  late final Directory directory;
  late final StreamSubscription<FileSystemEvent> subscription;

  static ProjectIntl instance = ProjectIntl(path: Directory.current.path);

  ProjectIntl({required String path}) {
    directory = Directory('$path/lib/l10n');
    if (!directory.existsSync()) {
      directory.createSync(recursive: true);
    }

    final List<FileSystemEntity> files = directory.listSync();

    for (final FileSystemEntity file in files) {
      if (file is File && file.path.endsWith('.arb')) {
        final arbFile = IntlArbFile(path: file.path, locale: getLocale(file.path));
        arbFiles[arbFile.locale] = arbFile;
      }
    }

    subscription = directory.watch(events: FileSystemEvent.all).listen((event) {
      final ext = extension(event.path);
      if (ext != '.arb') {
        return;
      }

      /// Arb 文件变化时，重新读取 arb 文件
      final locale = getLocale(event.path);
      getArb(locale).readStrings();

      /// Arb 文件变化时，发送事件
      if (event.type == FileSystemEvent.create || event.type == FileSystemEvent.delete) {
        IntlSocketServer.instance.postEvent({
          'type': 'arb_list_changed',
          'locale': locale,
        });
      } else {
        IntlSocketServer.instance.postEvent({
          'type': 'arb_changed',
          'locale': locale,
        });
      }

      /// Arb 文件变化时，重新运行 intl_utils 生成代码
      EasyDebounce.debounce('run_intl_utils', const Duration(seconds: 6), () {
        runIntlUtilsPackage();
      });
    });
  }

  final Map<String, IntlArbFile> arbFiles = {};

  IntlArbFile getArb(String locale) {
    if (arbFiles.containsKey(locale)) {
      return arbFiles[locale]!;
    }
    final String path = join(directory.path, 'intl_$locale.arb');
    final arbFile = IntlArbFile(path: path, locale: locale);
    arbFiles[locale] = arbFile;
    return arbFile;
  }

  String getLocale(String path) {
    return basenameWithoutExtension(path).replaceAll('intl_', '');
  }
}
